package com.zyl.Ecs.realtime.datasource;

import com.zyl.Ecs.common.utils.CUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @version v1.0
 * @ProjectName: Ecs
 * @Package: com.zyl.Ecs.realtime.datasource
 * @ClassName: DataSourceAspect
 * @Description
 *      切面类 - 用于配置数据源
 *      在执行service方法前，根据方法名或注解判断应该使用哪个数据源，
 *      并将对应的Enum（key）存入线程上下文ThreadLocal中。
 * @Author 翟玉龙
 * @Date 2024/12/6-13:53
 */
@Aspect
@Component
public class DataSourceAspect {

    /**
     * 配置写入操作切入点
     * 匹配service包下所有带有Master注解的方法，写入操作使用主库数据源
     */
    @Pointcut(value = "@annotation(Master) "
            + "&& execution(* com.zyl.Ecs.*.service..*.*(..)) ")
    public void writePointCut() {}

    /**
     * 配置读取操作切入点
     * 匹配service包下所有带有Slave注解的方法，读取操作使用从库数据源
     */
    @Pointcut(value = "@annotation(Slave) "
            + "&& execution(* com.zyl.Ecs.*.service..*.*(..)) ")
    public void readPointCut() {}


    /**
     * 前置通知
     * 在写入方法执行前切换到主库数据源
     *
     * @param joinPoint 切点
     */
    @Before("writePointCut()")
    public void write(JoinPoint joinPoint) {
        DataSourceContextHolder.master();
        CUtil.logInfo(String.format(
                "Method name: %s, DataSource: MASTER",
                joinPoint.getSignature().getName())
        );
    }

    /**
     * 前置通知
     * 在读取方法执行前切换到从库数据源
     *
     * @param joinPoint 切点
     */
    @Before("readPointCut()")
    public void readPointA(JoinPoint joinPoint) {
        DataSourceContextHolder.slave();
        CUtil.logInfo(String.format(
                "Method name: %s, DataSource: MASTER",
                joinPoint.getSignature().getName())
        );
    }


    /**
     * 后置通知
     * 所有方法执行结束后清空线程上下文
     */
    @After("readPointCut() || writePointCut()")
    public void remove() {
        DataSourceContextHolder.removeDataSourceType();
    }

}